import { Logger } from '@/utils/back';
import { getURLObj } from '@/utils/common';
import { NextRequest, NextResponse } from 'next/server';

const logger = Logger('login');

function writeCookie(
  res: NextResponse,
  name: string,
  value: string,
  expiresHours = 8
) {
  res.cookies.set(name, value, {
    maxAge: 60 * 60 * expiresHours, // 8 hours
    expires: new Date(Date.now() + 1000 * 60 * 60 * expiresHours),
    path: '/',
    httpOnly: true,
    sameSite: 'strict',
    secure: process.env.NODE_ENV === 'production',
  });
}

async function login(req: NextRequest) {
  const searchParams = req.nextUrl.searchParams;
  const authCode = searchParams.get('auth_code');
  const token = req.cookies.get('token');

  const redirectToErrorResponse = (msg: string) => {
    const urlObj = getURLObj('/api/error', req.url);
    urlObj.searchParams.set('msg', msg);

    return NextResponse.redirect(urlObj);
  };

  const backurl =
    searchParams.get('backurl') || getURLObj('/', req.url).toString();

  const redirectUrl = getURLObj('/redirect', req.url);
  redirectUrl.searchParams.set('backurl', backurl);
  redirectUrl.searchParams.set('hide', '1');

  if (!authCode) {
    return redirectToErrorResponse('No auth code provided');
  }

  let tokenRes;
  try {
    tokenRes = await fetch(
      `${process.env.NEXT_PUBLIC_DSZ_API_DOMAIN}/public/get_token?auth_code=${authCode}`,
      {
        method: 'GET',
        cache: 'no-cache',
      }
    );
  } catch (err: any) {
    return redirectToErrorResponse('Error fetching token:' + err.message);
  }

  const tokenData = await tokenRes.json();

  if (tokenData.success) {
    // const response = NextResponse.redirect(backurl);
    const response = NextResponse.redirect(redirectUrl);
    const lifeHours = 8;
    writeCookie(response, 'token', tokenData.token, lifeHours);
    writeCookie(response, 'token_ctime', Date.now() + '', lifeHours);
    writeCookie(
      response,
      'token_expire_time',
      Date.now() + 1000 * 3600 * lifeHours + '',
      lifeHours
    );

    logger.info('Login success', {
      token: tokenData.token,
      backurl,
    });
    return response;
  } else {
    return redirectToErrorResponse(tokenData.message);
  }
}

export async function GET(req: NextRequest) {
  return await login(req);
}
